package game

import (
	"fmt"
	"os"
	"server/GoUtil"
	"server/MergeConst"
	"server/conf"
	"sort"

	l "log"
	"server/db"
	"server/game/internal"
	"server/gamedata"
	"server/msg"
	"time"

	"math/rand"

	"github.com/robfig/cron/v3"

	"google.golang.org/protobuf/proto"

	"server/pkg/github.com/name5566/leaf/gate"
	"server/pkg/github.com/name5566/leaf/log"
	"server/pkg/github.com/name5566/leaf/timer"
)

var (
	G_GameLogicPtr *GameLogic
)

var isInitGameLogic = false
var RegisterNetWorkFunc = make(map[string]interface{})

func RegisterMsgProcessFunc(key string, value1 interface{}) {
	RegisterNetWorkFunc[key] = value1
}

func RunNetProcessByKey(key string, param []interface{}) {
	fun, ok := RegisterNetWorkFunc[key]
	if ok {
		fun.(func([]interface{}))(param)
	}
}

type LimitActPeriod struct {
	StartCronID cron.EntryID
	EndTimer    *timer.Timer
	StartTime   int32
	EndTime     int32
}

type GameLogic struct {
	Db_AccountInfo          db.Db_Account
	DailyTaskTimestamp      int64
	M_Players               map[int32]*Player
	m_CronEntryIDs          map[int]*LimitActPeriod
	Mdispatr                *timer.Dispatcher
	M_LimitActiveList       []int
	NotInitPlayer           *Player
	MReadyToRemoveList      map[*Player]*timer.Timer
	Mlogger                 *log.Logger
	MloggerErr              error
	Version                 int32
	M_SvrGlobal             db.SqlSvrGlobalStruct
	MChampshipsManager      *NewChampshipsManager
	MLimiteEventManager     *LimiteEventManager
	MPlayerProfileManager   *PlayerProfileManager
	MOldPlayerCompensateMgr *OldPlayerCompensateMgr
	MHttpManager            *HttpManager
}

func (gl *GameLogic) OpenTimestampTick() {
	gl.DailyTaskTimestamp = 0
	go func() {
		// 注释内容也可以使用

		ticker := time.NewTicker(time.Second * 1)

		for {
			select {
			case <-ticker.C:
				timeStamp := (int64)(time.Now().Unix())
				if timeStamp-gl.DailyTaskTimestamp >= 86400 {
					t := time.Unix(timeStamp, 0).Local()
					gl.DailyTaskTimestamp = timeStamp - (int64)(t.Hour()*3600+t.Minute()*60+t.Second())
					var a1 = []interface{}{gl.DailyTaskTimestamp}
					GoUtil.CallEvent(MergeConst.Notify_Daily_Renew, a1)
					gl.CreateDailyLogFile()
				}
				GoUtil.CallEvent(MergeConst.Notify_Clock_Tick_Sec, []interface{}{timeStamp})
				if gl.M_SvrGlobal.StartMileStoneSvrTime == 0 {
					gl.M_SvrGlobal.StartMileStoneSvrTime = int32(gl.DailyTaskTimestamp)
					gl.M_SvrGlobal.OpenSvrTime = int32(gl.DailyTaskTimestamp)
					db.FormatAllMemUpdateDb(&gl.M_SvrGlobal, "t_server_global_data", "Id")
				}
				if int32(timeStamp) >= gl.M_SvrGlobal.StartMileStoneSvrTime+MergeConst.G_MailStone_Period {
					deltaTime := int32(timeStamp) - gl.M_SvrGlobal.StartMileStoneSvrTime
					mod := deltaTime % MergeConst.G_MailStone_Period
					gl.M_SvrGlobal.StartMileStoneSvrTime = int32(timeStamp) - mod
					db.FormatAllMemUpdateDb(&gl.M_SvrGlobal, "t_server_global_data", "Id")
					var a1 = []interface{}{gl.M_SvrGlobal.StartMileStoneSvrTime}
					GoUtil.CallEvent(MergeConst.Notify_MileStone_Renew, a1)
				}
			}
		}
	}()
}

func (ad *GameLogic) IsExsitAccount(UserName string) bool {
	if ad.LoadDataFromDB(UserName) {
		return true
	}
	return false
}

func (ad *GameLogic) LoadDataFromDB(UserName string) bool {
	sqlStr := "SELECT * FROM t_account WHERE user_name = ?"

	if err := db.SqlDb.Get(&ad.Db_AccountInfo, sqlStr, UserName); err != nil {
		fmt.Printf("get data failed, err:%v\n", err)
		return false
	}

	return true
}

func (ad *GameLogic) NewAccountInsertDataToDB() bool {
	sqlStr := "INSERT INTO t_account(user_name, user_password) VALUES(:user_name, :user_password)"
	result, err := db.SqlDb.NamedExec(sqlStr, map[string]interface{}{
		"user_name":     ad.Db_AccountInfo.UserName,
		"user_password": ad.Db_AccountInfo.UserPassword,
	})
	if err != nil {
		fmt.Printf("named exec failed, err:%v\n", err)
		return false
	}
	insertId, err := result.LastInsertId()
	if err != nil {
		fmt.Printf("get last insert id failed, err:%v\n", err)
		return false
	}
	fmt.Printf("get last insert id failed, err:%v\n", insertId)

	insertId = insertId + int64(conf.Server.ServerID*100000)
	playerInfo := &db.ResPlayerBaseInfo{}
	playerInfo.DwUin = int32(insertId)
	playerInfo.Energy = 100
	playerInfo.Star = 0
	playerInfo.RecoverTime = int32(time.Now().Unix())
	playerInfo.Diamond = 0
	playerInfo.Level = 1
	playerInfo.Exp = 0
	playerInfo.StartOrderId = "1"
	playerInfo.MusicCode = 1
	playerInfo.Guild = 1
	playerInfo.PackUnlockCount = 5
	playerInfo.EnergyBuyCount = 0
	playerInfo.UserName = ad.Db_AccountInfo.UserName
	playerInfo.LoginTime = 0
	playerInfo.LogoutTime = 0
	playerInfo.Todayolinetime = 0
	playerInfo.Rolecreatetime = (int32)(time.Now().Unix())
	playerInfo.FaceBookId = ""
	db.FormatAllMemInsertDb(playerInfo, "t_player_baseinfo")

	return true
}

func (ad *GameLogic) PackResInfo(a gate.Agent, Func string, data []byte) {
	if a == nil {
		return
	}
	response := &msg.ClientRes{}
	response.Func = Func
	response.Cid = "cid"
	response.Info = data
	a.WriteMsg(response)
}

// 创建新玩家，初始化数据
func (ad *GameLogic) CreateNewPlayer(a gate.Agent, UserName string) {
	player := new(Player)
	internal.AsignPlayerToAgents(a, player) //绑定player和网络连接代理
	player.InitPlayer(UserName)

	ad.M_Players[player.M_DwUin] = player

}

func (ad *GameLogic) RebindPlayerAndAgent(a gate.Agent, player *Player) {
	internal.AsignPlayerToAgents(a, player)
	ad.M_Players[player.M_DwUin] = player
	player.Reconnect()

	timer1, _ := ad.MReadyToRemoveList[player]
	timer1.Disabled()
	ad.Mdispatr.ChanTimer <- timer1
	timer1.Stop()
	delete(G_GameLogicPtr.MReadyToRemoveList, player)
}

func (ad *GameLogic) GetPlayerByAgent(gate gate.Agent) *Player {

	_, ok := internal.Agents[gate]
	if ok {
		return internal.Agents[gate].(*Player)
	}
	return nil
}

func (ad *GameLogic) ReadAllConfigs() {
	gamedata.InitReadAllCfg()
	// gamedata.ReadConfigFromAllConfig("Activity.txt")
}

func G_getGameLogic() *GameLogic {
	if isInitGameLogic == false {
		G_GameLogicPtr = new(GameLogic)
		isInitGameLogic = true
		G_GameLogicPtr.Mdispatr = timer.NewDispatcher(10)
		G_GameLogicPtr.M_Players = make(map[int32]*Player)
		G_GameLogicPtr.MReadyToRemoveList = make(map[*Player]*timer.Timer)
		G_GameLogicPtr.NotInitPlayer = new(Player)
		G_GameLogicPtr.M_LimitActiveList = []int{}
		G_GameLogicPtr.LoadSvrGlobalData()
		G_GameLogicPtr.CreateChamshipsMgr()
		G_GameLogicPtr.CreateLimiteEventManager()
		G_GameLogicPtr.CreateProfileManager()
		G_GameLogicPtr.CreateCompensateMgr()
		G_GameLogicPtr.OpenTimestampTick()
		G_GameLogicPtr.ReadAllConfigs()
		G_GameLogicPtr.RegisterEvent()
		G_GameLogicPtr.RegisterNetWorkFunc()
		G_GameLogicPtr.InitActivity()
		G_GameLogicPtr.GetVersion()
		// G_GameLogicPtr.CreateHttpManager()
	}
	return G_GameLogicPtr
}

func (ad *GameLogic) DisorderLuaTable(length int, Cnt int) []int {

	// length := len(tb)
	rand.Seed(time.Now().Unix())
	indexList := []int{}
	contentList := []int{}
	copy := []int{}
	for i := 0; i < Cnt; i++ {
		index := rand.Intn(length - i)
		if len(indexList) == 0 {
			indexList = append(indexList, index)
		} else {
			for n := 0; n < len(copy); n++ {
				if index >= copy[n] {
					index = index + 1
				}
			}
			indexList = append(indexList, index)
		}
		copy = []int{}
		for j := 0; j < len(indexList); j++ {
			copy = append(copy, indexList[j])
		}

		sort.Slice(copy, func(i, j int) bool { return copy[i] < copy[j] })
	}
	contentList = indexList[:]
	return contentList
}

func (ad *GameLogic) GetVersion() {
	sqlStr := "SELECT * FROM t_gameserver WHERE id = ?"
	sqlStruck := db.SqlVersionStruct{}
	IsHaveDataDb := false
	sqlStruck.Id = 1
	G_GameLogicPtr.Version = 0
	if err := db.SqlDb.Get(&sqlStruck, sqlStr, 1); err != nil {
		G_GameLogicPtr.Version = 1
		IsHaveDataDb = false
	} else {
		G_GameLogicPtr.Version = sqlStruck.IsClose + 1
		IsHaveDataDb = true
	}
	sqlStruck.IsClose = G_GameLogicPtr.Version

	if IsHaveDataDb {
		db.FormatAllMemUpdateDb(&sqlStruck, "t_gameserver", "id")
	} else {
		db.FormatAllMemInsertDb(&sqlStruck, "t_gameserver")
	}
}

func (ad *GameLogic) SendServerVersion(a gate.Agent) {
	res := &msg.ResServerVersion{}
	res.Version = G_GameLogicPtr.Version
	data, _ := proto.Marshal(res)
	G_getGameLogic().PackResInfo(a, "ResServerVersion", data)
}

func (ad *GameLogic) ClearData(args []interface{}) {
	player := args[0].(*Player)
	if player != nil {
		player.ClearData()
	}
	delete(ad.M_Players, player.M_DwUin)
	go func() {
		LeafTimer := ad.Mdispatr.AfterFunc(time.Duration(3*60)*time.Second, func() {
			delete(G_GameLogicPtr.MReadyToRemoveList, player)
		})
		G_GameLogicPtr.MReadyToRemoveList[player] = LeafTimer
		(<-ad.Mdispatr.ChanTimer).Cb()
	}()

}

func (ad *GameLogic) FindOfflinePlayer(dwUin int32) *Player {
	for k, _ := range G_GameLogicPtr.MReadyToRemoveList {
		if k.M_DwUin == dwUin {
			return k
		}
	}
	return nil
}

func (ad *GameLogic) InitPassportInsertDb(player *Player, StartSvrTime int32, EndSvrTime int32, ConfigActId int) int32 {
	st := &db.SqlLimitPassportStruct{}
	st.CurFreeLv = 0
	st.CurPayLv = 0
	st.DwUin = player.M_DwUin
	st.IsPay = 0
	st.Star = 0
	st.StartSvrTime = StartSvrTime
	st.EndSvrTime = EndSvrTime
	st.Status = 0
	st.ActiveID = 0
	st.ConfigActId = int32(ConfigActId)
	activityID, _ := db.FormatAllMemInsertDb(st, "t_player_LimitPassport")

	return int32(activityID)
}

func (ad *GameLogic) InitPromotionInsertDb(player *Player, StartSvrTime int32, EndSvrTime int32, ConfigActId int) int32 {
	st := &db.SqlLimitPromotionStruct{}
	st.DwUin = player.M_DwUin
	st.IsPay = 0
	st.StartSvrTime = StartSvrTime
	st.EndSvrTime = EndSvrTime
	st.ActiveID = 0
	st.ConfigActId = int32(ConfigActId)
	activityID, _ := db.FormatAllMemInsertDb(st, "t_player_LimitPromotion")

	return int32(activityID)
}

func (ad *GameLogic) InitInfinitePackInsertDb(player *Player, StartSvrTime int32, EndSvrTime int32, ConfigActId int) int32 {
	st := &db.SqlLimitInfinitePackStruct{}
	st.DwUin = player.M_DwUin
	st.CurGear = 1
	st.StartSvrTime = StartSvrTime
	st.EndSvrTime = EndSvrTime
	st.ActiveID = 0
	st.ConfigActId = int32(ConfigActId)
	activityID, _ := db.FormatAllMemInsertDb(st, "t_player_LimitInfinitePack")

	return int32(activityID)
}

func (ad *GameLogic) Init7DayLoginInsertDb(player *Player, StartSvrTime int32, EndSvrTime int32, ConfigActId int) int32 {
	st := &db.SqlSevenDayLoginStruct{}
	st.DwUin = player.M_DwUin
	st.LastGetTime = 0
	st.StartSvrTime = StartSvrTime
	st.EndSvrTime = EndSvrTime
	st.ActiveID = 0
	st.GetIndex = 0
	st.ConfigActId = int32(ConfigActId)
	activityID, _ := db.FormatAllMemInsertDb(st, "t_player_Limit7DayLogin")

	return int32(activityID)
}

func (ad *GameLogic) InitCardCollectInsertDb(player *Player, StartSvrTime int32, EndSvrTime int32, ConfigActId int) int32 {
	st := &db.SqlCardCollectStruct{}
	st.DwUin = player.M_DwUin

	st.StartSvrTime = StartSvrTime
	st.EndSvrTime = EndSvrTime
	st.ActiveID = 0
	st.Fragment = 0
	st.CardInfo = ""
	st.ConfigActId = int32(ConfigActId)
	activityID, _ := db.FormatAllMemInsertDb(st, "t_player_card_data")

	return int32(activityID)
}

func (ad *GameLogic) LoadSvrGlobalData() {
	sqlStr := "SELECT * FROM t_server_global_data WHERE Id = ?"

	ad.M_SvrGlobal = db.SqlSvrGlobalStruct{}

	if err := db.SqlDb.Get(&ad.M_SvrGlobal, sqlStr, 1); err != nil {
		fmt.Printf("get data failed, err:%v\n", err)
		timeStamp := time.Now().Unix()
		t := time.Unix(timeStamp, 0).Local()
		zero := timeStamp - (int64)(t.Hour()*3600+t.Minute()*60+t.Second())
		ad.M_SvrGlobal.StartMileStoneSvrTime = int32(zero)
		ad.M_SvrGlobal.Id = 1
		db.FormatAllMemInsertDb(&ad.M_SvrGlobal, "t_server_global_data")
	} else {

	}
}

func (ad *GameLogic) OpenNewLimitActivity(args []interface{}) {
	go func() {
		for k, player := range internal.Agents {
			if player == ad.NotInitPlayer {
				continue
			}
			notify := &msg.NotifyLimitedTimeActiveData{}
			notify.MActiveList = []*msg.LimitedTimeActiveStruct{}

			id := args[0].(int)
			activityCfg := gamedata.GetConfigByName("Activity")
			record := activityCfg.Index(id).(*gamedata.ActivityRecord)

			act := &msg.LimitedTimeActiveStruct{}
			act.StartSvrTime = args[1].(int32)
			act.EndSvrTime = args[2].(int32)
			act.Type = int32(record.Type)
			if act.Type == 1 {
				act.ActiveID = ad.InitPassportInsertDb(player.(*Player), act.StartSvrTime, act.EndSvrTime, id)
			}
			if act.Type == 2 {
				act.ActiveID = ad.InitPromotionInsertDb(player.(*Player), act.StartSvrTime, act.EndSvrTime, id)
			}
			if act.Type == 3 {
				act.ActiveID = ad.InitInfinitePackInsertDb(player.(*Player), act.StartSvrTime, act.EndSvrTime, id)
			}
			if act.Type == 4 {
				act.ActiveID = ad.Init7DayLoginInsertDb(player.(*Player), act.StartSvrTime, act.EndSvrTime, id)
			}
			if act.Type == 5 {
				act.ActiveID = ad.InitCardCollectInsertDb(player.(*Player), act.StartSvrTime, act.EndSvrTime, id)
			}
			notify.MActiveList = append(notify.MActiveList, act)
			data, _ := proto.Marshal(notify)
			ad.PackResInfo(k, "NotifyLimitedTimeActiveData", data)

		}
	}()

}

func (ad *GameLogic) RegisterEvent() {

	GoUtil.RegisterEvent(MergeConst.Notify_Socket_Closed, ad.ClearData, nil)
	GoUtil.RegisterEvent(MergeConst.Notify_Socket_Connect, ad.NewPlayerConnect, nil)
	GoUtil.RegisterEvent(MergeConst.OpenNewLimitActivity, ad.OpenNewLimitActivity, nil)
}

func (ad *GameLogic) NewPlayerConnect(args []interface{}) {
	a := args[0].(gate.Agent)
	internal.AsignPlayerToAgents(a, ad.NotInitPlayer)
}

func (ad *GameLogic) ReplaceExistPlayerAndAgent(a gate.Agent, player *Player) {
	agent := player.GetAgentByPlayer()

	notify := &msg.ForceKickOut{}
	data, _ := proto.Marshal(notify)
	if agent != nil && a != agent {
		G_getGameLogic().PackResInfo(agent, "ForceKickOut", data)
		internal.AsignPlayerToAgents(agent, ad.NotInitPlayer)
	}
	internal.AsignPlayerToAgents(a, player)
	ad.M_Players[player.M_DwUin] = player
}

func (ad *GameLogic) SendMassage(dwUin int32, Func string, data []byte) bool {
	player, ok := ad.M_Players[dwUin]
	if ok {
		agent := player.GetAgentByPlayer()
		if agent != nil {
			G_getGameLogic().PackResInfo(agent, Func, data)
			return true
		}
	}
	return false
}

func (ad *GameLogic) FileExist(path string) bool {
	_, err := os.Lstat(path)
	return !os.IsNotExist(err)
}

func (ad *GameLogic) CreateDailyLogFile() {

	now := time.Unix(ad.DailyTaskTimestamp, 0).Local()

	filename := fmt.Sprintf("%d%02d%02d_%02d_%02d_%02d.log",
		now.Year(),
		now.Month(),
		now.Day(),
		now.Hour(),
		now.Minute(),
		now.Second())

	filepathname := "log/" + filename
	if !ad.FileExist(filepathname) {
		if ad.Mlogger != nil {
			ad.Mlogger.Close()
		}
		ad.Mlogger, ad.MloggerErr = log.NewDailyLog(now, "Debug", "log", l.LstdFlags)
		if ad.MloggerErr != nil {
			return
		}
		log.Export(ad.Mlogger)
	} else {
		ad.Mlogger, ad.MloggerErr = log.BindLoggerToFile("Debug", filepathname, l.LstdFlags)
		log.Export(ad.Mlogger)
	}
	ad.Mlogger.Debug("CreateDailyLogFile")
}

func (ad *GameLogic) RegisterNetWorkFunc() {

	RegisterMsgProcessFunc("ReqPlayerBaseInfo", ReqPlayerBaseInfofunction)
	RegisterMsgProcessFunc("UpdateBaseItemInfo", UpdateBaseItemInfofunction)
	RegisterMsgProcessFunc("UpdateKeyValueData", UpdateKeyValueDatafunction)
	RegisterMsgProcessFunc("ReqPlayerEmitUnlockData", ReqPlayerEmitUnlockDatafunction)
	RegisterMsgProcessFunc("UpdatePlayerEmitUnlockData", UpdatePlayerEmitUnlockDatafunction)
	RegisterMsgProcessFunc("ReqPlayerPackData", ReqPlayerPackDataFunc)
	RegisterMsgProcessFunc("UpdatePlayerPackData", UpdatePlayerPackDataFunc)
	RegisterMsgProcessFunc("ReqPlayerChessData", ReqPlayerChessDataFunc)
	RegisterMsgProcessFunc("UpdatePlayerChessData", UpdatePlayerChessDataFunc)
	RegisterMsgProcessFunc("UpdateChessColorData", UpdateChessColorDataFunc)
	RegisterMsgProcessFunc("ReqChessColorData", ResChessColorDataFunc)

	RegisterMsgProcessFunc("ReqPlayerGiftData", ReqPlayerGiftDataFunc)
	RegisterMsgProcessFunc("UpdatePlayerGiftData", UpdatePlayerGiftDataFunc)
	RegisterMsgProcessFunc("ReqPlayerOrderData", ReqPlayerOrderDataFunc)
	RegisterMsgProcessFunc("UpdatePlayerOrderData", UpdatePlayerOrderDataFunc)
	RegisterMsgProcessFunc("ReqUnlockingChestID", ReqUnlockingChestIDFunc)
	RegisterMsgProcessFunc("ReqChestUnlockCD", ReqChestUnlockCDFunc)

	RegisterMsgProcessFunc("ReqEmitMergeMap", ReqEmitMergeMapFunc)
	RegisterMsgProcessFunc("ReqEmitCountMap", ReqResEmitCountMapFunc)
	RegisterMsgProcessFunc("ReqEmitCDStartData", ReqEmitCDStartDataFunc)
	RegisterMsgProcessFunc("UpdateEmitMergeMap", UpdateEmitMergeMapFunc)
	RegisterMsgProcessFunc("UpdateEmitCountMap", UpdateEmitCountMapFunc)
	RegisterMsgProcessFunc("ReqEmitSubCD", ReqEmitSubCDFunc)

	RegisterMsgProcessFunc("ReqDecorateData", ReqDecorateDatafunc)
	RegisterMsgProcessFunc("UpdateDecorateData", UpdateDecorateDataFunc)

	RegisterMsgProcessFunc("ReqShopData", ReqShopDatafunc)
	RegisterMsgProcessFunc("ReqShopBuy", ReqShopBuyFunc)
	RegisterMsgProcessFunc("ReqRenewItemBuyCnt", ReqRenewItemBuyCntFunc)

	RegisterMsgProcessFunc("ReqBriefEmailData", ReqBriefEmailDataFunc)
	RegisterMsgProcessFunc("ReqDetailEmailData", ReqDetailEmailDataFunc)
	RegisterMsgProcessFunc("ReqGetEmailReward", ReqGetEmailRewardFunc)
	RegisterMsgProcessFunc("ReqDeleteEmail", ReqDeleteEmailFunc)

	RegisterMsgProcessFunc("ReqLimitPassportDetail", ReqLimitPassportDetailFunc)
	RegisterMsgProcessFunc("ReqPromotionDetail", ReqPromotionDetailFunc)
	RegisterMsgProcessFunc("ReqInfinitePackDetail", ReqInfinitePackDetailFunc)

	RegisterMsgProcessFunc("Req7DayLoginDetail", Req7DayLoginDetailFunc)
	RegisterMsgProcessFunc("ReqGet7DayLoginPack", ReqGet7DayLoginPackFunc)

	RegisterMsgProcessFunc("Req7DaySignal", Req7DaySignalFunc)
	RegisterMsgProcessFunc("Req7DayCallbackSignal", Req7DayCallbackSignal)

	RegisterMsgProcessFunc("ReqGetLimitPassportReward", ReqGetLimitPassportRewardFunc)
	RegisterMsgProcessFunc("ReqBuyLimitPromotionReward", ReqBuyLimitPromotionRewardFunc)
	RegisterMsgProcessFunc("ReqBuyInfinitePack", ReqBuyInfinitePackFunc)

	RegisterMsgProcessFunc("ReqPayPassport", ReqPayPassportFunc)
	RegisterMsgProcessFunc("ReqActiveAddStar", ReqActiveAddStarFunc)

	RegisterMsgProcessFunc("ReqOfflineReconnect", ReqOfflineReconnectFunc)

	RegisterMsgProcessFunc("ReqOpenNewPig", ReqOpenNewPigFunc)
	RegisterMsgProcessFunc("ReqPigDetailInfo", ReqPigDetailInfoFunc)
	RegisterMsgProcessFunc("UpdateFinishOrderDiamond", UpdateFinishOrderDiamondFunc)
	RegisterMsgProcessFunc("ReqGetPigReward", ReqGetPigRewardFunc)
	RegisterMsgProcessFunc("ReqDropPigReward", ReqDropPigRewardFunc)

	RegisterMsgProcessFunc("ReqLevelUpPackInfo", ReqLevelUpPackInfoFunc)
	RegisterMsgProcessFunc("ReqBuyLevelUpPack", ReqBuyLevelUpPackFunc)

	RegisterMsgProcessFunc("ReqGrowthFundInfo", ReqGrowthFundInfoFunc)
	RegisterMsgProcessFunc("ReqBuyGrowthFund", ReqBuyGrowthFundFunc)
	RegisterMsgProcessFunc("ReqGetGrowthFundWard", ReqGetGrowthFundWardFunc)
	RegisterMsgProcessFunc("ReqRemoveAd", ReqRemoveAdFunc)

	RegisterMsgProcessFunc("ReqSupremeGiftInfo", ReqSupremeGiftInfoFunc)
	RegisterMsgProcessFunc("ReqBuySupremeGift", ReqBuySupremeGiftFunc)

	RegisterMsgProcessFunc("ReqIllustratedInfo", ReqIllustratedInfoFunc)
	RegisterMsgProcessFunc("ReqGetIllustrateItemReward", ReqGetIllustrateItemRewardFunc)
	RegisterMsgProcessFunc("UpdateIllustrateItem", UpdateIllustrateItemFunc)

	RegisterMsgProcessFunc("ReqCardCollectDetail", ReqCardCollectDetailFunc)
	RegisterMsgProcessFunc("ReqGetCardAlbumReward", ReqGetCardAlbumRewardFunc)
	RegisterMsgProcessFunc("ReqGetAllCardReward", ReqGetAllCardRewardFunc)
	RegisterMsgProcessFunc("ReqAddCard", ReqAddCardFunc)
	RegisterMsgProcessFunc("ReqUnpackCard", ReqUnpackCardFunc)
	RegisterMsgProcessFunc("ReqAddMasterCard", ReqAddMasterCardFunc)
	RegisterMsgProcessFunc("ReqUseMasterCard", ReqUseMasterCardFunc)
	RegisterMsgProcessFunc("ReqBuyStickerItem", ReqBuyStickerItemFunc)

	RegisterMsgProcessFunc("ReqExchangeCardBoxData", ReqExchangeCardBoxDataFunc)
	RegisterMsgProcessFunc("ReqDonateFriendCard", ReqDonateFriendCardFunc)
	RegisterMsgProcessFunc("ReqGetDonateCard", ReqGetDonateCardFunc)
	RegisterMsgProcessFunc("ReqExchangeCard", ReqExchangeCardFunc)
	RegisterMsgProcessFunc("ReqReceiptCard", ReqReceiptCardFunc)
	RegisterMsgProcessFunc("ReqCompleteExchangeCard", ReqCompleteExchangeCardFunc)
	RegisterMsgProcessFunc("ReqGetExchangeCard", ReqGetExchangeCardFunc)
	RegisterMsgProcessFunc("ReqRefuseExchange", ReqRefuseExchangeFunc)
	RegisterMsgProcessFunc("ReqRequestCard", ReqRequestCardFunc)
	RegisterMsgProcessFunc("ReqCompleteRequestCard", ReqCompleteRequestCardFunc)
	RegisterMsgProcessFunc("ReqRefuseRequestCard", ReqRefuseRequestCardFunc)
	RegisterMsgProcessFunc("ReqGetRequestCard", ReqGetRequestCardFunc)

	RegisterMsgProcessFunc("ReqDailyTaskData", ResDailyTaskDataFunc)
	RegisterMsgProcessFunc("UpdateDailyTaskData", UpdateDailyTaskDataFunc)
	RegisterMsgProcessFunc("RenewDailyTaskData", RenewDailyTaskDataFunc)
	RegisterMsgProcessFunc("RenewWeekyActiveData", RenewWeekyActiveDataFunc)

	RegisterMsgProcessFunc("ReqMileStoneData", ResMileStoneDataFunc)
	RegisterMsgProcessFunc("UpdateMileStoneData", UpdateMileStoneDataFunc)
	RegisterMsgProcessFunc("RenewMileStoneData", RenewMileStoneDataFunc)

	RegisterMsgProcessFunc("ReqChampshipData", ReqChampshipDataFunc)
	RegisterMsgProcessFunc("ReqChampshipAddScore", ReqChampshipAddScoreFunc)
	RegisterMsgProcessFunc("ReqChampshipAddTime", ReqChampshipAddTimeFunc)
	RegisterMsgProcessFunc("ReqChampshipReward", ReqChampshipRewardFunc)
	RegisterMsgProcessFunc("ReqPlayerChampshipData", ReqPlayerChampshipData)

	RegisterMsgProcessFunc("ReqAdPackData", ReqAdPackDataFunc)
	RegisterMsgProcessFunc("ReqWatchAdPack", ReqWatchAdPackFunc)

	RegisterMsgProcessFunc("ReqPlayerSingleData", ReqPlayerSingleDataFunc)
	RegisterMsgProcessFunc("ReqOpenNewbiePack", ReqOpenNewbiePackFunc)
	RegisterMsgProcessFunc("ReqBuyNewbiePack", ReqBuyNewbiePackFunc)
	RegisterMsgProcessFunc("ReqAddNoAdCnt", ReqAddNoAdCntFunc)
	RegisterMsgProcessFunc("ReqAddWatchAdCnt", ReqAddWatchAdCntFunc)

	RegisterMsgProcessFunc("ReqPlayerPayData", ReqPlayerPayDataFunc)
	RegisterMsgProcessFunc("ReqAddPay", ReqAddPayFunc)

	RegisterMsgProcessFunc("ReqLimitData", ReqLimitDataFunc)
	RegisterMsgProcessFunc("ReqAddLimitTime", ReqAddLimitTimeFunc)

	RegisterMsgProcessFunc("ReqGenSuperOrder", ReqGenSuperOrderFunc)
	RegisterMsgProcessFunc("ReqEndSuperOrder", ReqEndSuperOrder)
	RegisterMsgProcessFunc("ReqCompleteDoubleHit", ReqCompleteDoubleHit)
	RegisterMsgProcessFunc("ReqTagThief", ReqTagThief)

	RegisterMsgProcessFunc("ReqFriendData", ReqFriendDataFunc)
	RegisterMsgProcessFunc("ReqWillPlayerDetail", ReqWillPlayerDetailFunc)
	RegisterMsgProcessFunc("ReqAddFriendData", ReqAddFriendDataFunc)
	RegisterMsgProcessFunc("ReqAllAddFriendInfo", ReqAllAddFriendInfoFunc)
	RegisterMsgProcessFunc("ReqAgreeFriendReq", ReqAgreeFriendReqFunc)
	RegisterMsgProcessFunc("ReqRefuseFriendReq", ReqRefuseFriendReqFunc)
	RegisterMsgProcessFunc("ReqDeleteFriend", ReqDeleteFriendFunc)
	RegisterMsgProcessFunc("ReqAutoFBAddFriend", ReqAutoFBAddFriend)
	RegisterMsgProcessFunc("ReqAutoAddInviteFriend", ReqAutoAddInviteFriend)
	RegisterMsgProcessFunc("ReqRecommendFriendList", ReqRecommendFriendList)
	RegisterMsgProcessFunc("ReqInviteFriendData", ReqInviteFriendData)
	RegisterMsgProcessFunc("ReqSelfInvited", ReqSelfInvited)
	RegisterMsgProcessFunc("ReqGetInviteReward", ReqGetInviteReward)
	RegisterMsgProcessFunc("ReqFriendTreasureData", ReqFriendTreasureData)
	RegisterMsgProcessFunc("ReqUpdateFriendStar", ReqUpdateFriendStar)

	RegisterMsgProcessFunc("ReqPlayerProfileData", ReqPlayerProfileDataFunc)
	RegisterMsgProcessFunc("ReqUpdatePlayerProfile", ReqUpdatePlayerProfileFunc)
	RegisterMsgProcessFunc("ReqPlayerBriefProfileData", ReqPlayerBriefProfileDataFunc)
	RegisterMsgProcessFunc("ReqFriendEventData", ReqFriendEventDataFunc)
	RegisterMsgProcessFunc("ReqUpdateFBPicURL", ReqUpdateFBPicURLFunc)

	RegisterMsgProcessFunc("ReqBindFacebookAccount", ReqBindFacebookAccount)
	RegisterMsgProcessFunc("ReqOnlyBindFacebook", ReqOnlyBindFacebook)
	RegisterMsgProcessFunc("ReqUnBindFacebook", ReqUnBindFacebook)
	RegisterMsgProcessFunc("ReqSynGameData", ReqSynGameData)

	RegisterMsgProcessFunc("ReqPlayerPetData", ReqPlayerPetData)
	RegisterMsgProcessFunc("ReqUpdatePetProfile", ReqUpdatePetProfile)

	RegisterMsgProcessFunc("ReqPetHomeData", ReqPetHomeData)
	RegisterMsgProcessFunc("ReqOpenOtherPetHome", ReqOpenOtherPetHome)
	RegisterMsgProcessFunc("ReqCompleteMiniGame", ReqCompleteMiniGame)
	RegisterMsgProcessFunc("ReqOpenSelfPet", ReqOpenSelfPet)
	RegisterMsgProcessFunc("ReqPetHomeInterActST", ReqPetHomeInterActST)
	RegisterMsgProcessFunc("ReqShiftVisitPet", ReqShiftVisitPet)
	RegisterMsgProcessFunc("ReqCallBackPet", ReqCallBackPet)
	RegisterMsgProcessFunc("ReqUnlockDecorate", ReqUnlockDecorate)
	RegisterMsgProcessFunc("ReqSaveSelectDecorate", ReqSaveSelectDecorate)
}

func (ad *GameLogic) ResPlayerEmitUnlockData(param []interface{}) {
	data := (param[0].(*Player).GetIFGameData("PlayerEmitUnlockData"))
	data.(*PlayerEmitUnlockData).ResPlayerEmitUnlockData(param[0].(*Player))
}

func (ad *GameLogic) broadcastInfoAllPlayer(Func string, data []byte) {
	for k, player := range internal.Agents {
		if player.(*Player) == ad.NotInitPlayer {
			continue
		}
		ad.PackResInfo(k, Func, data)
	}

}

func (ad *GameLogic) JudgeIsActivity(c *cron.Cron, Id int) int {
	activityCfg := gamedata.GetConfigByName("Activity")
	record := activityCfg.Index(Id).(*gamedata.ActivityRecord)

	timeStamp := time.Now().Unix()
	t := time.Unix(timeStamp, 0).Local()
	nianchu := timeStamp - (int64)(t.Hour()*3600+t.Minute()*60+t.Second()) - int64((t.YearDay()-1)*3600*24)

	key := ad.m_CronEntryIDs[record.Id]
	Schedule := c.Entry(key.StartCronID).Schedule
	Next := Schedule.Next(time.Unix(nianchu, 0))

	if timeStamp >= Next.Unix() && timeStamp <= Next.Unix()+int64(record.Duration) {
		return 2
	} else {
		if timeStamp < Next.Unix() {
			return 1
		}
	}
	return 3
}

func (ad *GameLogic) CalcDeltaEndTime(c *cron.Cron, Id int) int32 {
	activityCfg := gamedata.GetConfigByName("Activity")
	record := activityCfg.Index(Id).(*gamedata.ActivityRecord)

	timeStamp := time.Now().Unix()
	t := time.Unix(timeStamp, 0).Local()
	nianchu := timeStamp - (int64)(t.Hour()*3600+t.Minute()*60+t.Second()) - int64((t.YearDay()-1)*3600*24)

	key := ad.m_CronEntryIDs[record.Id]
	Schedule := c.Entry(key.StartCronID).Schedule
	Next := Schedule.Next(time.Unix(nianchu, 0))
	return int32(Next.Unix() + int64(record.Duration) - timeStamp)
}

func (ad *GameLogic) GetActiveParamById(Id int) *LimitActPeriod {
	v, ok := ad.m_CronEntryIDs[Id]
	if ok {
		return v
	}
	return nil
}

func (ad *GameLogic) CreateLimiteEventManager() {
	ad.MLimiteEventManager = new(LimiteEventManager)
	ad.MLimiteEventManager.InitManager()
}

func (ad *GameLogic) CreateProfileManager() {
	ad.MPlayerProfileManager = new(PlayerProfileManager)
	ad.MPlayerProfileManager.InitManager()
}

func (ad *GameLogic) CreateChamshipsMgr() {
	ad.MChampshipsManager = new(NewChampshipsManager)
	ad.MChampshipsManager.InitManager()
}

func (ad *GameLogic) CreateCompensateMgr() {
	ad.MOldPlayerCompensateMgr = new(OldPlayerCompensateMgr)
	ad.MOldPlayerCompensateMgr.InitManager()
}

func (ad *GameLogic) CreateHttpManager() {

	go func() {
		ad.MHttpManager = new(HttpManager)
		ad.MHttpManager.InitRounter()
	}()

}

func (ad *GameLogic) InitActivity() {
	ad.m_CronEntryIDs = make(map[int]*LimitActPeriod)
	activityCfg := gamedata.GetConfigByName("Activity")
	c := cron.New()

	timeStamp := time.Now().Unix()
	t := time.Unix(timeStamp, 0).Local()
	nianchu := timeStamp - (int64)(t.Hour()*3600+t.Minute()*60+t.Second()) - int64((t.YearDay()-1)*3600*24)

	for i := 0; i < activityCfg.NumRecord(); i++ {
		record := activityCfg.Record(i).(*gamedata.ActivityRecord)
		start := record.StartTime
		var LAP = LimitActPeriod{}

		LAP.StartCronID, _ = c.AddFunc(start, func() {
			fmt.Println("Next: UTC", c.Entry(LAP.StartCronID).Next.Unix())
			G_GameLogicPtr.M_LimitActiveList = append(G_GameLogicPtr.M_LimitActiveList, record.Id)
			cur := int32(time.Now().Unix())
			GoUtil.CallEvent(MergeConst.OpenNewLimitActivity, []interface{}{record.Id, cur, cur + int32(record.Duration), record.Type})
			go func() {
				LeafTimer := ad.Mdispatr.AfterFunc(time.Duration(record.Duration)*time.Second, func() {
					GoUtil.CallEvent(MergeConst.CloseNewLimitActivity, []interface{}{record})
					G_GameLogicPtr.M_LimitActiveList = GoUtil.DeleteEleByValue(G_GameLogicPtr.M_LimitActiveList, record.Id)
				})
				LAP.EndTimer = LeafTimer
				(<-ad.Mdispatr.ChanTimer).Cb()
			}()
		})
		ad.m_CronEntryIDs[record.Id] = &LAP
	}
	c.Start()
	for k, v := range ad.m_CronEntryIDs {
		ret := ad.JudgeIsActivity(c, k)
		if ret == 3 { //已经结束
			delete(ad.m_CronEntryIDs, k)
		}
		if ret == 2 {
			key := k
			value := v
			G_GameLogicPtr.M_LimitActiveList = append(G_GameLogicPtr.M_LimitActiveList, k)
			go func() {
				delta := ad.CalcDeltaEndTime(c, key)
				LeafTimer := ad.Mdispatr.AfterFunc(time.Duration(delta)*time.Second, func() {
					record := activityCfg.Index(key).(*gamedata.ActivityRecord)
					GoUtil.CallEvent(MergeConst.CloseNewLimitActivity, []interface{}{record})
					G_GameLogicPtr.M_LimitActiveList = GoUtil.DeleteEleByValue(G_GameLogicPtr.M_LimitActiveList, key)
				})
				value.EndTimer = LeafTimer
				Schedule := c.Entry(value.StartCronID).Schedule
				Next := Schedule.Next(time.Unix(nianchu, 0))
				value.StartTime = int32(Next.Unix())
				value.EndTime = int32(Next.Unix()) + activityCfg.Index(key).(*gamedata.ActivityRecord).Duration
				(<-ad.Mdispatr.ChanTimer).Cb()
			}()
		}

	}

}
